import React, { forwardRef, useEffect, useState, useImperativeHandle, useRef } from 'react';
import FunctionEdit from './functionEdit';
import { Button, Card, Checkbox, Form, Input, InputNumber, message, Select, Tree } from 'antd';
import { CheckboxChangeEvent } from 'antd/es/checkbox';
import { FeatureConfigEnum, featureConfOptions } from '.';
interface IProps {
  nodeData: any;
  checkedData: any;
}

const FunctionTree = forwardRef((props: IProps, ref: any) => {
  const { nodeData, checkedData } = props;
  const [treeNodeInfo, setTreeNodeInfo] = useState<any>({});
  const [featureConfVal, setFeatureConfVal] = useState<FeatureConfigEnum>(FeatureConfigEnum.App);
  const [selectAll, setSelectAll] = useState(false);
  // 判断是否获取当前树数据的keys,nodes
  const hasAllKeys = useRef(false);
  const allTreeKeys = useRef<any>({});
  const allTreeNodes = useRef<any>({});
  const [treeData, setTreeData] = useState<any[]>([]);
  const [checkedKeys, setCheckedKeys] = useState<any[]>([]);
  const [checkedNodes, setCheckedNodes] = useState<any>([]);
  // 子节点选中，父节点算是半选的
  const [halfCheckedKeys, setHalfCheckedKeys] = useState<any[]>([]);
  const [visible, setVisible] = useState(false);
  const [functionData, setFunctionData] = useState<any>(null);

  useImperativeHandle(ref, () => {
    return {
      validateSort,
      getAllCheckedData,
    };
  });

  // 转换成节点格式数据
  const formatTreeData = (
    treeList: any,
    checkedData: any,
    checkedNodes: any,
    allTreeKeys: any,
    allTreeNodes: any,
  ) => {
    return treeList.map((item: any) => {
      let { children, ...treeNode } = item;

      if (Array.isArray(children) && children.length > 0) {
        children = formatTreeData(children, checkedData, checkedNodes, allTreeKeys, allTreeNodes);
      }
      let checkedNode = checkedData.find(item => item.sid === treeNode.sid);
      let newNode = {
        ...treeNode,
        otherName: checkedNode?.otherName || treeNode.otherName,
        funcParam: checkedNode?.funcParam || treeNode.funcParam,
        tips: checkedNode?.tips || treeNode.tips,
        sortNum: checkedNode?.sortNum || treeNode.sortNum,
        children,
        key: treeNode.sid,
        title: treeNode.itemName,
      };
      if (checkedNode && checkedNode.isCheckAll === 1) {
        checkedNodes.push(newNode);
      }
      if (!hasAllKeys.current) {
        allTreeKeys.push(newNode.sid);
        allTreeNodes.push(newNode);
      }
      return newNode;
    });
  };

  useEffect(() => {
    let { nodeData = {}, checkedData = {} } = treeNodeInfo;
    // 当前功能配置对应的数据
    let currentTreeData = nodeData[featureConfVal] || [];
    let currentCheckedData = checkedData[featureConfVal] || [];
    let currentCheckedKeys = currentCheckedData
      .map(item => item.isCheckAll === 1 && item.sid)
      .filter(Boolean);
    let currentHalfCheckedKeys = currentCheckedData
      .map(item => item.isCheckAll === 2 && item.sid)
      .filter(Boolean);
    let checkedNodes: any = [];
    let currentAllKeys = (allTreeKeys.current[featureConfVal] =
      allTreeKeys.current[featureConfVal] || []);
    let currentAllNodes = (allTreeNodes.current[featureConfVal] =
      allTreeNodes.current[featureConfVal] || []);
    if (currentAllKeys.length === 0) hasAllKeys.current = false;
    let treeData = formatTreeData(
      currentTreeData,
      currentCheckedData,
      checkedNodes,
      currentAllKeys,
      currentAllNodes,
    );
    // 比对一下，看看是否全选。
    let checked =
      currentAllKeys.length === currentCheckedKeys.length && currentCheckedKeys.length > 0;
    hasAllKeys.current = true;
    setTreeData(treeData);
    setCheckedKeys(currentCheckedKeys);
    setHalfCheckedKeys(currentHalfCheckedKeys);
    setCheckedNodes(checkedNodes);
    setSelectAll(checked);
  }, [treeNodeInfo, featureConfVal]);

  useEffect(() => {
    setTreeNodeInfo({ checkedData: checkedData ?? {}, nodeData: nodeData ?? {} });
  }, [checkedData, nodeData]);

  // 全选按钮
  const onSelectAll = (e: CheckboxChangeEvent) => {
    let keys: React.Key[] = [];
    let nodes: any = [];
    if (e.target.checked) {
      keys = [...allTreeKeys.current[featureConfVal]];
      nodes = [...allTreeNodes.current[featureConfVal]];
    }
    if (!e.target.checked) {
      formatUncheckedTreeNode(treeData, []);
    }
    setCheckedKeys(keys);
    setHalfCheckedKeys([]);
    setCheckedNodes(nodes);
    setSelectAll(e.target.checked);
  };
  // 修改功能配置
  const onChangeFeatureConfig = async (value: FeatureConfigEnum) => {
    let checkedNodes = await validateSort();
    if (!checkedNodes) {
      message.warning('当前功能配置有校验错误');
      return;
    }
    // 比对一下，看看是否全选。
    setFeatureConfVal(value);
  };

  const onChangeOtherName = (e, nodeData) => {
    let value = e.target.value;
    nodeData.otherName = value;
    setCheckedNodes([...checkedNodes]);
  };

  const getParentNode = (key: React.Key, tree: any): any => {
    let parentNode: any;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some(item => item.key === key)) {
          parentNode = node;
        } else if (getParentNode(key, node.children)) {
          parentNode = getParentNode(key, node.children);
        }
      }
    }
    return parentNode!;
  };

  const onChangeSort = (value, nodeData) => {
    const currentNode = nodeData;
    const lastValue = currentNode.sortNum;
    currentNode.sortNum = value;
    let validateNodes: any = [];
    // 判断节点是不是一级节点 level = 1
    if (currentNode.level === 1) {
      validateNodes = treeData;
    } else {
      // 从选中的节点中检索父级。
      const parentNode = getParentNode(nodeData.sid, treeData);
      validateNodes = parentNode.children;
    }
    if (!value) {
      currentNode.status = 'error';
      currentNode.message = '请输入排列序号';
    } else {
      let isRepeat = false;
      // 当前节点修改之后，是否与其他节点重复
      isRepeat = validateNodes.find(item => item.sortNum === value && item.sid !== currentNode.sid);
      if (isRepeat) {
        currentNode.status = 'error';
        currentNode.message = '该序号已存在';
      } else {
        currentNode.status = undefined;
        currentNode.message = '';
      }
    }
    // 当前节点修改之后，获取之前序号重复的节点数据。若仅有一个节点与之重复，则去掉错误新，
    let lastRepeatNodes = validateNodes.filter(
      item => lastValue && item.sid !== currentNode.sid && item.sortNum === lastValue,
    );
    if (lastRepeatNodes.length === 1) {
      lastRepeatNodes[0].status = undefined;
      lastRepeatNodes[0].message = '';
    }
    setCheckedNodes([...checkedNodes]);
  };

  // 功能编辑引用当前编辑的树状节点。编辑的数据更新到树状节点
  const editFunction = functionData => {
    setFunctionData(functionData);
    setVisible(true);
  };
  const onClose = () => {
    setVisible(false);
    setFunctionData(null);
  };

  const onSave = async values => {
    const { funcParam, tips } = values;
    functionData.funcParam = funcParam;
    functionData.tips = tips;
    setCheckedNodes([...checkedNodes]);
  };

  const renderTreeNode = nodeData => {
    return (
      <div
        style={{ display: 'flex', marginBottom: nodeData.message ? '20px' : '0' }}
        key={nodeData.key}
      >
        <span className="check-title">{nodeData.itemName}</span>
        <Input
          size="small"
          value={nodeData.otherName}
          className="check-inp"
          placeholder="请输入别名（用于终端显示）"
          onChange={e => onChangeOtherName(e, nodeData)}
        />
        {[...checkedKeys, ...halfCheckedKeys].includes(nodeData.sid) && (
          <div style={{ display: 'flex' }}>
            <div style={{ margin: '0 16px' }}>
              <InputNumber
                value={nodeData.sortNum}
                size="small"
                placeholder="请输入排列序号"
                min={1}
                max={500}
                onChange={value => onChangeSort(value, nodeData)}
                status={nodeData.status}
                style={{ position: 'relative', width: '120px' }}
              />
              {nodeData.message && (
                <div style={{ position: 'absolute', color: '#ff4d4f' }}>{nodeData.message}</div>
              )}
            </div>
            <Button type="primary" size="small" onClick={() => editFunction(nodeData)}>
              功能编辑
            </Button>
          </div>
        )}
      </div>
    );
  };

  const formatUncheckedTreeNode = (treeList, halfAndCheckedKeys) => {
    treeList.forEach(item => {
      let { children } = item;
      if (Array.isArray(children) && children.length > 0) {
        formatUncheckedTreeNode(children, halfAndCheckedKeys);
      }
      let findIndex = halfAndCheckedKeys.findIndex(key => key === item.sid);
      if (findIndex === -1) {
        item.sortNum = null;
        item.status = undefined;
        item.message = undefined;
        item.funcParam = null;
        item.tips = null;
      }
    });
  };

  const onCheck = (
    checkedKeysValue: React.Key[],
    e: { checked: boolean; checkedNodes: any; halfCheckedKeys: any },
  ) => {
    // 比对一下，看看是否全选。
    let checked = allTreeKeys.current[featureConfVal].length === checkedKeysValue.length;
    formatUncheckedTreeNode(treeData, [...checkedKeysValue, ...e.halfCheckedKeys]);
    setSelectAll(checked);
    setCheckedKeys(checkedKeysValue);
    setHalfCheckedKeys(e.halfCheckedKeys);
    setCheckedNodes(e.checkedNodes);
  };

  const setValidateNodes = (treeList: any, halfCheckedKeys, checkedKeys, validateNodes) => {
    treeList.forEach(item => {
      let { children } = item;

      if (Array.isArray(children) && children.length > 0) {
        setValidateNodes(children, halfCheckedKeys, checkedKeys, validateNodes);
      }
      if (halfCheckedKeys.includes(item.sid)) {
        item.isCheckAll = 2;
        validateNodes.push(item);
      }
      if (checkedKeys.includes(item.sid)) {
        item.isCheckAll = 1;
        validateNodes.push(item);
      }
    });
  };
  // 校验是否有排序的错误提示
  const validateSort = async () => {
    let halfAndCheckedNodes: any = [];
    setValidateNodes(treeData, halfCheckedKeys, checkedKeys, halfAndCheckedNodes);
    halfAndCheckedNodes.forEach(node => {
      if (!node.sortNum) {
        node.status = 'error';
        node.message = '请输入排列序号';
      }
    });
    let hasError = halfAndCheckedNodes.some(item => item.status);
    if (!hasError) {
      treeNodeInfo.checkedData[featureConfVal] = halfAndCheckedNodes;
      treeNodeInfo.nodeData[featureConfVal] = treeData;
      setTreeNodeInfo({
        ...treeNodeInfo,
      });
    }
    setTreeData([...treeData]);
    return hasError ? false : halfAndCheckedNodes;
  };
  // 获取所有配置的选中数据
  const getAllCheckedData = () => {
    let { checkedData } = treeNodeInfo;
    return Object.values(checkedData).reduce((result: any[], current: any) => {
      return [...result, ...current];
    }, []);
  };

  return (
    <div>
      <Card title="功能配置">
        <div className="form-tree">
          <div className="form-select">
            <Form.Item label=" " colon={false}>
              <Select
                options={featureConfOptions}
                value={featureConfVal}
                onChange={onChangeFeatureConfig}
              />
            </Form.Item>
          </div>
          <div className="tree-check">
            <Checkbox checked={selectAll} onChange={onSelectAll}>
              全选按钮
            </Checkbox>
            {treeData.length > 0 ? (
              <Tree
                height={600}
                checkable
                defaultExpandAll={true}
                checkedKeys={checkedKeys}
                onCheck={onCheck}
                treeData={treeData}
                titleRender={renderTreeNode}
              />
            ) : (
              ''
            )}
          </div>
        </div>
      </Card>
      <FunctionEdit open={visible} onClose={onClose} onSave={onSave} functionData={functionData} />
    </div>
  );
});

export default FunctionTree;
